﻿/*
 * This file is part of SCWS.
 * SCWS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 * 
 * Foobar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with SCWS.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Xml.Schema;
using System.Data;
using System.Globalization;
using System.Security.Principal;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Administration;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Monitoring;


namespace Scws
{

    public partial class Om : System.Web.Services.WebService
    {

        private DataSet ScheduleMM(String rms, ReadOnlyCollection<PartialMonitoringObject> objects, DateTime start,
                            DateTime stop, MaintenanceModeReason mmr, TraversalDepth td,
                            String comment, ref DataSet results)
        {

            DataSet ds = QueryMonitoringObjectsByClassName(rms, "", "Microsoft.SystemCenter.RootManagementServer");

            string rmsFqdn = ds.Tables[0].Rows[0]["DisplayName"].ToString();

            foreach (PartialMonitoringObject m in objects)
            {
                if (m.DisplayName == rmsFqdn)
                {
                    AddMMResultRow(ref results, m, "errorrms");
                }

                else
                {
                    //if (m.MonitoringClassIds.Contains(GetMonitoringClass(rms, "System.Group").Id))
                    //{
                    //    ScheduleMM(rms, GetGroupMembers(m.Id.ToString(), rms), start, stop, mmr, td, comment, ref results);
                    //}
                    //else
                    //{
                    if (m.InMaintenanceMode == true)
                    {
                        MaintenanceWindow thisMw = m.GetMaintenanceWindow();

                        DateTime mmendtime = thisMw.ScheduledEndTime;

                        if (stop <= mmendtime)
                        {
                            AddMMResultRow(ref results, m, "alreadyinmm");
                        }
                        else
                        {
                            m.UpdateMaintenanceMode(stop, mmr, comment, td);
                            AddMMResultRow(ref results, m, "updated");
                        }
                    }
                    else
                    {
                        m.ScheduleMaintenanceMode(start, stop, mmr, comment, td);
                        AddMMResultRow(ref results, m, "added");
                    }
                    //}
                }
            }

            return results;

        }


        
        private static DataSet AddMMResultRow(ref DataSet ds, PartialMonitoringObject monobj, String result)
        {
            DataRow row = ds.Tables["MaintenanceModeResults"].NewRow();
            row["MonitoringObjectDisplayName"] = monobj.DisplayName;
            row["MonitoringObjectID"] = monobj.Id.ToString();
            row["MonitoringObjectPath"] = monobj.Path;
            row["Result"] = result;
            ds.Tables["MaintenanceModeResults"].Rows.Add(row);

            return ds;
        }


        private static void VerifyMMParams(ref int minutes, ref string comment)
        {
            if (minutes < 5 | minutes >= 288000)
                throw new System.InvalidOperationException("Minutes parameter must be an integer between 5 and 288000");

            if (comment.Length > 1000)
                throw new System.InvalidOperationException("Comment must be 1000 chars or less");
        }


        /// <summary>
        /// Returns a monitoringclass object when provided with the monitoring class name as a string
        /// </summary>
        /// <param name="sMonitoringClassName"></param>
        /// <returns></returns>
        private static MonitoringClass GetMonitoringClass(string rms, string monitoringclassname)
        {
            ManagementGroup mg = GetMG(rms);
            MonitoringClassCriteria criteria = new MonitoringClassCriteria("Name LIKE '" + monitoringclassname + "'");
            ReadOnlyCollection<MonitoringClass> classes = mg.GetMonitoringClasses(criteria);

            if (classes.Count != 1)
                throw new TooManyObjectsFoundException("Too many or not enough classes found");

            return classes[0];
        }


        /// <summary>
        /// function to return a maintenance mode reason object when supplied with the correct name as a string
        /// </summary>
        /// <param name="reason"></param>
        /// <returns>maintenancemodereason</returns>
        private static MaintenanceModeReason GetMMReason(string reason)
        {
            MaintenanceModeReason results = new MaintenanceModeReason();
            bool isfound = new bool();
            isfound = false;
            foreach (MaintenanceModeReason r in Enum.GetValues(typeof(MaintenanceModeReason)))
            {
                if (reason.ToLower() == r.ToString().ToLower())
                {
                    isfound = true;
                    results = r;
                }
            }

            if (!isfound)
                throw new Microsoft.EnterpriseManagement.Common.ObjectNotFoundException("Maintenance mode reason not found");

            return results;
        }


        /// <summary>
        /// function to connect to an RMS.  Will throw an exception if unsucessful.
        /// </summary>
        /// <param name="rms"></param>
        /// <returns></returns>
        private static ManagementGroup GetMG(string rms)
        {
            return new ManagementGroup(rms);
        }


        private DataSet GetMMResultsDataSet()
        {
            DataSet ds = new DataSet();

            try
            {
                ds.ReadXmlSchema(XSD_MAINTENANCEMODERESULTS);
            }
            catch
            {
                ds.Dispose();
                throw new Scws.Om.XsdNotFoundException(XSD_MAINTENANCEMODERESULTS);
            }
            return ds;
        }




        ///// <summary>
        ///// Returns a ReadOnlyCollection of PartialMonitoringObjects given an Id as a string
        ///// </summary>
        ///// <param name="groupId">monitoringobjectid of group object</param>
        ///// <param name="rms">RMS server name</param>
        ///// <returns>ReadOnlyCollection of partialmonitoringobjects</returns>
        //private static ReadOnlyCollection<PartialMonitoringObject> GetGroupMembers(string groupId, string rms)
        //{
        //    ManagementGroup mg = GetMG(rms);

        //    PartialMonitoringObject monobj = mg.GetPartialMonitoringObject(new Guid(groupId));

        //    return monobj.GetRelatedPartialMonitoringObjects();
        //}
    }
}
